<!doctype html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  
  <meta name="generator" content="Hugo 0.98.0" />

  
  <meta name="description" content="走在通往幸福的路上">
  

  
  <link rel="apple-touch-icon" sizes="180x180" href="https://blog.v5u.win/apple-touch-icon.png">

  
  <link rel="icon" type="image/png" sizes="32x32" href="https://blog.v5u.win/favicon-32x32.png">

  
  <link rel="icon" type="image/png" sizes="16x16" href="https://blog.v5u.win/favicon-16x16.png">

  
  <link rel="manifest" href="https://blog.v5u.win/site.webmanifest">

  
  <link rel="mask-icon" href="https://blog.v5u.win/safari-pinned-tab.svg" color="">

  <meta name="msapplication-TileColor" content="">

  <meta name="theme-color" content="">

  
  <link rel="stylesheet" href="https://blog.v5u.win/css/bootstrap.min.css" />

  
  <title>Go 代码规范 | 为吾优</title>
  

  <style>
body {
  min-width: 300px;
}

.custom-navbar {
  margin-bottom: 1em;
  height: 60px;
}

.custom-navbar a {
  display: inline-block; 
  padding: 18px 0;
  margin-right: 1em; 
  font-weight: bold; 
}

.custom-navbar a:hover,
.custom-navbar a:focus {
  text-decoration: none; 
}

@media print {
  .custom-navbar {
    display: none;
  }
}

article {
  padding-bottom: 1em;
}

img {
  max-width: 100%;
}


body {
  background-color: #fff;
}



body {
  color: #212529;
}



a {
  color: #007bff;
}



a:hover,
a:focus {
  color: #0056b3;
}



.custom-navbar {
  background-color: #212529;
}



.custom-navbar a {
  color: rgba(255,255,255,.75);
}



.custom-navbar a:hover,
.custom-navbar a:focus {
  color: rgba(255,255,255,1);
}



.container {
  max-width: 800px;
}





</style>
</head>

<body>
  <nav class="custom-navbar">
  <div class="container">
    
    <a href="/">文章</a>
    
    <a href="/tags/">标签</a>
    
    <a href="/about/">关于</a>
    
    <a href="/index.xml">RSS</a>
    
  </div>
</nav>
  
  <div class="container">
    <article>
      <h1>Go 代码规范</h1>
<h2 id="golang代码规范">Golang代码规范</h2>
<p>参考 <a href="https://golang.org/doc/effective_go.html">https://golang.org/doc/effective_go.html</a></p>
<p>[本文参考blog][1]</p>
<p>[TOC]</p>
<h3 id="项目目录结构规范">项目目录结构规范</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-sh" data-lang="sh"><span style="display:flex;"><span>PROJECT_NAME
</span></span><span style="display:flex;"><span>├── README.md 介绍软件及文档入口
</span></span><span style="display:flex;"><span>├── bin 编译好的二进制文件,执行./build.sh自动生成，该目录也用于程序打包
</span></span><span style="display:flex;"><span>├── build.sh 自动编译的脚本
</span></span><span style="display:flex;"><span>├── doc 该项目的文档
</span></span><span style="display:flex;"><span>├── pack 打包后的程序放在此处
</span></span><span style="display:flex;"><span>├── pack.sh 自动打包的脚本，生成类似xxxx.20170713_14:45:35.tar.gz的文件，放在pack文件下
</span></span><span style="display:flex;"><span>├── public 公共文件/静态文件
</span></span><span style="display:flex;"><span>└── src 该项目的源代码
</span></span><span style="display:flex;"><span>    ├── main 项目主函数
</span></span><span style="display:flex;"><span>    ├── test 测试
</span></span><span style="display:flex;"><span>    ├── app 项目代码
</span></span><span style="display:flex;"><span>    ├── research 在实现该项目中探究的一些程序
</span></span><span style="display:flex;"><span>    └── vendor 存放go的库
</span></span><span style="display:flex;"><span>        ├── github.com/xxx 第三方库
</span></span><span style="display:flex;"><span>        └── xxx.com/abc 公司内部的公共库
</span></span><span style="display:flex;"><span>&lt;/code&gt;&lt;/pre&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>项目的目录结构尽量做到简明、层次清楚。
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">```</span>sh
</span></span><span style="display:flex;"><span>./app
</span></span><span style="display:flex;"><span>├── bootstrap	//入口引导文件
</span></span><span style="display:flex;"><span>├── cache
</span></span><span style="display:flex;"><span>├── config  //项目配置 项目配置文件简单，配置项少。大部分配置公司要用配置中心统一配置。
</span></span><span style="display:flex;"><span>├── controller  //request请求处理中心 ——&amp;gt; controller ——&amp;gt; Response / view
</span></span><span style="display:flex;"><span>├── library //项目工具库
</span></span><span style="display:flex;"><span>├── log         //日志
</span></span><span style="display:flex;"><span>├── middleware  //中间件
</span></span><span style="display:flex;"><span>├── model       //data model.xorm -——&amp;gt; 数据库表映射模型
</span></span><span style="display:flex;"><span>├── plugin  //插件--自己开发/自己找的 --delete
</span></span><span style="display:flex;"><span>├── route       //路由管理
</span></span><span style="display:flex;"><span>├── service //前端数据获取操作 service
</span></span><span style="display:flex;"><span>&lt;/code&gt;&lt;/pre&gt;
</span></span><span style="display:flex;"><span>* * *
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#### 文件名命名规范</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>用小写，尽量见名思义，看见文件名就可以知道这个文件下的大概内容，对于源代码里的文件，文件名要很好的代表了一个模块实现的功能。
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">### 命名规范</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#### 包名</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>包名用小写,使用短命名,尽量和标准库不要冲突
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#### 接口名</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>单个函数的接口名以”er”作为后缀，如Reader,Writer
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>接口的实现则去掉“er”
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">```</span>go
</span></span><span style="display:flex;"><span>type Reader interface <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span>&lt;/code&gt;&lt;/pre&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>两个函数的接口名综合两个函数名
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">```</span>go
</span></span><span style="display:flex;"><span>type WriteFlusher interface <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>    Write<span style="color:#f92672">([]</span>byte<span style="color:#f92672">)</span> <span style="color:#f92672">(</span>int, error<span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>    Flush<span style="color:#f92672">()</span> error
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span>&lt;/code&gt;&lt;/pre&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>三个以上函数的接口名，类似于结构体名
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">```</span>go
</span></span><span style="display:flex;"><span>type Car interface <span style="color:#f92672">{</span>
</span></span><span style="display:flex;"><span>    Start<span style="color:#f92672">([]</span>byte<span style="color:#f92672">)</span> 
</span></span><span style="display:flex;"><span>    Stop<span style="color:#f92672">()</span> error
</span></span><span style="display:flex;"><span>    Recover<span style="color:#f92672">()</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">}</span>
</span></span><span style="display:flex;"><span>&lt;/code&gt;&lt;/pre&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#### 变量</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>全局变量：采用驼峰命名法，仅限在包内的全局变量，包外引用需要写接口，提供调用 局部变量：驼峰式，小写字母开头
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">#### 常量</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>常量：大写，采用下划线
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">### import 规范</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>import在多行的情况下，goimports会自动帮你格式化，在一个文件里面引入了一个package，建议采用如下格式：
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">```</span>go
</span></span><span style="display:flex;"><span>import <span style="color:#f92672">(</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">)</span>
</span></span><span style="display:flex;"><span>&lt;/code&gt;&lt;/pre&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>如果你的包引入了三种类型的包，标准库包，程序内部包，第三方包，建议采用如下方式进行组织你的包：
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">```</span>go
</span></span><span style="display:flex;"><span>import <span style="color:#f92672">(</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;encoding/json&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;strings&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;myproject/model&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;myproject/controller&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;git.obc.im/obc/utils&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;git.obc.im/dep/beego&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;git.obc.im/dep/mysql&#34;</span>
</span></span><span style="display:flex;"><span>    // 空白引入需要添加注释
</span></span><span style="display:flex;"><span>		// 空白导入应该只在主包或测试包中，或者有一个注释证明它是正确的
</span></span><span style="display:flex;"><span>		_ <span style="color:#e6db74">&#34;github.com/jinzhu/gorm/dialects/mysql&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">)</span>  
</span></span></code></pre></div><p>在项目中不要使用相对路径引入包：</p>
<p>// 这是不好的导入</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">import</span> <span style="color:#960050;background-color:#1e0010">“</span>..<span style="color:#f92672">/</span><span style="color:#a6e22e">net</span><span style="color:#960050;background-color:#1e0010">”</span>
</span></span></code></pre></div><p>// 这是正确的做法</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">import</span> <span style="color:#960050;background-color:#1e0010">“</span><span style="color:#a6e22e">xxxx</span>.<span style="color:#a6e22e">com</span><span style="color:#f92672">/</span><span style="color:#a6e22e">proj</span><span style="color:#f92672">/</span><span style="color:#a6e22e">net</span><span style="color:#960050;background-color:#1e0010">”</span>
</span></span></code></pre></div><h4 id="函数名">函数名</h4>
<p>函数名采用驼峰命名法，尽量不要使用下划线</p>
<h3 id="错误处理">错误处理</h3>
<p>error作为函数的值返回,必须尽快对error进行处理</p>
<p>采用独立的错误流进行处理</p>
<p>不要采用这种方式</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// error handling
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    } <span style="color:#66d9ef">else</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// normal code
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    }
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">/</span><span style="color:#a6e22e">code</span>&gt;&lt;<span style="color:#f92672">/</span><span style="color:#a6e22e">pre</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">而要采用下面的方式</span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">```go
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    if err != nil {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        // error handling
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        return // or continue, etc.
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    }
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    // normal code
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">&lt;/code&gt;&lt;/pre&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">如果返回值需要初始化，则采用下面的方式
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">```</span><span style="color:#66d9ef">go</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">x</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">f</span>()
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// error handling
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#66d9ef">return</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#75715e">// use x
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>&lt;<span style="color:#f92672">/</span><span style="color:#a6e22e">code</span>&gt;&lt;<span style="color:#f92672">/</span><span style="color:#a6e22e">pre</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">####</span> <span style="color:#a6e22e">Panic</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">在逻辑处理中禁用panic</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">在main包中只有当实在不可运行的情况采用panic</span><span style="color:#960050;background-color:#1e0010">，</span><span style="color:#a6e22e">例如文件无法打开</span><span style="color:#960050;background-color:#1e0010">，</span><span style="color:#a6e22e">数据库无法连接导致程序无法</span> <span style="color:#a6e22e">正常运行</span><span style="color:#960050;background-color:#1e0010">，</span><span style="color:#a6e22e">但是对于其他的package对外的接口不能有panic</span><span style="color:#960050;background-color:#1e0010">，</span><span style="color:#a6e22e">只能在包内采用</span><span style="color:#960050;background-color:#1e0010">。</span> <span style="color:#a6e22e">建议在main包中使用log</span>.<span style="color:#a6e22e">Fatal来记录错误</span><span style="color:#960050;background-color:#1e0010">，</span><span style="color:#a6e22e">这样就可以由log来结束程序</span><span style="color:#960050;background-color:#1e0010">。</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">####</span> <span style="color:#a6e22e">Recover</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">recover用于捕获runtime的异常</span><span style="color:#960050;background-color:#1e0010">，</span><span style="color:#a6e22e">禁止滥用recover</span><span style="color:#960050;background-color:#1e0010">，</span><span style="color:#a6e22e">在开发测试阶段尽量不要用recover</span><span style="color:#960050;background-color:#1e0010">，</span><span style="color:#a6e22e">recover一般放在你认为会有不可预期的异常的地方</span><span style="color:#960050;background-color:#1e0010">。</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">```go
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">func server(workChan &lt;-chan *Work) {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    for work := range workChan {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        go safelyDo(work)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    }
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">}
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">func safelyDo(work *Work) {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    defer func() {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        if err := recover(); err != nil {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">            log.Println(&#34;work failed:&#34;, err)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        }
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    }()
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    // do 函数可能会有不可预期的异常
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    do(work)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">}
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">&lt;/code&gt;&lt;/pre&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">#### Defer
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">defer在函数return之前执行，对于一些资源的回收用defer是好的，但也禁止滥用defer，defer是需要消耗性能的,所以频繁调用的函数尽量不要使用defer。
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">```</span><span style="color:#66d9ef">go</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// Contents returns the file&#39;s contents as a string.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">Contents</span>(<span style="color:#a6e22e">filename</span> <span style="color:#66d9ef">string</span>) (<span style="color:#66d9ef">string</span>, <span style="color:#66d9ef">error</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">f</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Open</span>(<span style="color:#a6e22e">filename</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#34;&#34;</span>, <span style="color:#a6e22e">err</span>
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">defer</span> <span style="color:#a6e22e">f</span>.<span style="color:#a6e22e">Close</span>()  <span style="color:#75715e">// f.Close will run when we&#39;re finished.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">result</span> []<span style="color:#66d9ef">byte</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">buf</span> <span style="color:#f92672">:=</span> make([]<span style="color:#66d9ef">byte</span>, <span style="color:#ae81ff">100</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">for</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">n</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">f</span>.<span style="color:#a6e22e">Read</span>(<span style="color:#a6e22e">buf</span>[<span style="color:#ae81ff">0</span>:])
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">result</span> = append(<span style="color:#a6e22e">result</span>, <span style="color:#a6e22e">buf</span>[<span style="color:#ae81ff">0</span>:<span style="color:#a6e22e">n</span>]<span style="color:#f92672">...</span>) <span style="color:#75715e">// append is discussed later.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">==</span> <span style="color:#a6e22e">io</span>.<span style="color:#a6e22e">EOF</span> {
</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">break</span>
</span></span><span style="display:flex;"><span>            }
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#34;&#34;</span>, <span style="color:#a6e22e">err</span>  <span style="color:#75715e">// f will be closed if we return here.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>        }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> string(<span style="color:#a6e22e">result</span>), <span style="color:#66d9ef">nil</span> <span style="color:#75715e">// f will be closed if we return here.
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>}
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">/</span><span style="color:#a6e22e">code</span>&gt;&lt;<span style="color:#f92672">/</span><span style="color:#a6e22e">pre</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">###</span> <span style="color:#a6e22e">控制结构</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">####</span> <span style="color:#66d9ef">if</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">if接受初始化语句</span><span style="color:#960050;background-color:#1e0010">，</span><span style="color:#a6e22e">约定如下方式建立局部变量</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">```go
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">if err := file.Chmod(0664); err != nil {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    return err
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">}
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">&lt;/code&gt;&lt;/pre&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">#### for
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">采用短声明建立局部变量
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">```</span><span style="color:#66d9ef">go</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">sum</span> <span style="color:#f92672">:=</span> <span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> <span style="color:#a6e22e">i</span> <span style="color:#f92672">:=</span> <span style="color:#ae81ff">0</span>; <span style="color:#a6e22e">i</span> &lt; <span style="color:#ae81ff">10</span>; <span style="color:#a6e22e">i</span><span style="color:#f92672">++</span> {
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">sum</span> <span style="color:#f92672">+=</span> <span style="color:#a6e22e">i</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">/</span><span style="color:#a6e22e">code</span>&gt;&lt;<span style="color:#f92672">/</span><span style="color:#a6e22e">pre</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">####</span> <span style="color:#66d9ef">range</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">如果只需要第一项</span><span style="color:#960050;background-color:#1e0010">（</span><span style="color:#a6e22e">key</span><span style="color:#960050;background-color:#1e0010">），</span><span style="color:#a6e22e">就丢弃第二个</span><span style="color:#960050;background-color:#1e0010">：</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">```go
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">for key := range m {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    if key.expired() {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">        delete(m, key)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    }
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">}
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">&lt;/code&gt;&lt;/pre&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">如果只需要第二项，则把第一项置为下划线
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">```</span><span style="color:#66d9ef">go</span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">sum</span> <span style="color:#f92672">:=</span> <span style="color:#ae81ff">0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">value</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">array</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">sum</span> <span style="color:#f92672">+=</span> <span style="color:#a6e22e">value</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">/</span><span style="color:#a6e22e">code</span>&gt;&lt;<span style="color:#f92672">/</span><span style="color:#a6e22e">pre</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">####</span> <span style="color:#66d9ef">return</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">尽早return</span><span style="color:#960050;background-color:#1e0010">：</span><span style="color:#a6e22e">一旦有错误发生</span><span style="color:#960050;background-color:#1e0010">，</span><span style="color:#a6e22e">马上返回</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">```go
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">f, err := os.Open(name)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">if err != nil {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    return err
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">}
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">d, err := f.Stat()
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">if err != nil {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    f.Close()
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    return err
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">}
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">codeUsing(f, d)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">&lt;/code&gt;&lt;/pre&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">### 方法的接收器
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">名称 一般采用strcut的第一个字母且为小写，而不是this，me或者self
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">```</span><span style="color:#66d9ef">go</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">type</span> <span style="color:#a6e22e">T</span> <span style="color:#66d9ef">struct</span>{} 
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">p</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">T</span>)<span style="color:#a6e22e">Get</span>(){}
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">/</span><span style="color:#a6e22e">code</span>&gt;&lt;<span style="color:#f92672">/</span><span style="color:#a6e22e">pre</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">如果接收者是map</span>,<span style="color:#a6e22e">slice或者chan</span><span style="color:#960050;background-color:#1e0010">，</span><span style="color:#a6e22e">不要用指针传递</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">```go
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">//Map
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">package main
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">import (
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    &#34;fmt&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">type mp map[string]string
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">func (m mp) Set(k, v string) {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    m[k] = v
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">}
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">func main() {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    m := make(mp)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    m.Set(&#34;k&#34;, &#34;v&#34;)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    fmt.Println(m)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">}
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">//Channel
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">package main
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">import (
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    &#34;fmt&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">type ch chan interface{}
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">func (c ch) Push(i interface{}) {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    c &amp;lt;- i
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">}
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">func (c ch) Pop() interface{} {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    return &amp;lt;-c
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">}
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">func main() {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    c := make(ch, 1)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    c.Push(&#34;i&#34;)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    fmt.Println(c.Pop())
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">}
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">&lt;/code&gt;&lt;/pre&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">如果需要对slice进行修改，通过返回值的方式重新赋值
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">```</span><span style="color:#66d9ef">go</span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">//Slice
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> (
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">slice</span> []<span style="color:#66d9ef">byte</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">s</span> <span style="color:#f92672">:=</span> make(<span style="color:#a6e22e">slice</span>, <span style="color:#ae81ff">0</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">s</span> = <span style="color:#a6e22e">s</span>.<span style="color:#a6e22e">addOne</span>(<span style="color:#ae81ff">42</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">s</span>)
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">s</span> <span style="color:#a6e22e">slice</span>) <span style="color:#a6e22e">addOne</span>(<span style="color:#a6e22e">b</span> <span style="color:#66d9ef">byte</span>) []<span style="color:#66d9ef">byte</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> append(<span style="color:#a6e22e">s</span>, <span style="color:#a6e22e">b</span>)
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">/</span><span style="color:#a6e22e">code</span>&gt;&lt;<span style="color:#f92672">/</span><span style="color:#a6e22e">pre</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#a6e22e">如果接收者是含有sync</span>.<span style="color:#a6e22e">Mutex或者类似同步字段的结构体</span><span style="color:#960050;background-color:#1e0010">，</span><span style="color:#a6e22e">必须使用指针传递避免复制</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#e6db74">```go
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">package main
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">import (
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    &#34;sync&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">type T struct {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    m sync.Mutex
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">}
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">func (t *T) lock() {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    t.m.Lock()
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">}
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">/*
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">Wrong !!!
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">func (t T) lock() {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    t.m.Lock()
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">}
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">*/
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">func main() {
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    t := new(T)
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    t.lock()
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">}
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">&lt;/code&gt;&lt;/pre&gt;
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">如果接收者是大的结构体或者数组，使用指针传递会更有效率。
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">```</span><span style="color:#66d9ef">go</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> (
</span></span><span style="display:flex;"><span>    <span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">T</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">data</span> [<span style="color:#ae81ff">1024</span>]<span style="color:#66d9ef">byte</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">t</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">T</span>) <span style="color:#a6e22e">Get</span>() <span style="color:#66d9ef">byte</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">t</span>.<span style="color:#a6e22e">data</span>[<span style="color:#ae81ff">0</span>]
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">t</span> <span style="color:#f92672">:=</span> new(<span style="color:#a6e22e">T</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#a6e22e">t</span>.<span style="color:#a6e22e">Get</span>())
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">/</span><span style="color:#a6e22e">code</span>&gt;&lt;<span style="color:#f92672">/</span><span style="color:#a6e22e">pre</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#960050;background-color:#1e0010">###</span> <span style="color:#a6e22e">注释</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#ae81ff">1.</span> <span style="color:#a6e22e">所有的</span> <span style="color:#a6e22e">public</span> <span style="color:#a6e22e">方法和变量都要添加注释</span>
</span></span><span style="display:flex;"><span>  <span style="color:#ae81ff">2.</span> <span style="color:#a6e22e">注释格式为</span><span style="color:#960050;background-color:#1e0010">：</span><span style="color:#a6e22e">name</span> <span style="color:#a6e22e">describeContent</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>&lt;<span style="color:#a6e22e">pre</span>&gt;&lt;<span style="color:#a6e22e">code</span> <span style="color:#a6e22e">class</span>=<span style="color:#e6db74">&#34;language-go line-numbers&#34;</span>&gt;    <span style="color:#75715e">// TubeName1 channel 1
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#a6e22e">TubeName1</span> = <span style="color:#e6db74">&#34;通道一&#34;</span>
</span></span><span style="display:flex;"><span>&lt;<span style="color:#f92672">/</span><span style="color:#a6e22e">code</span>&gt;&lt;<span style="color:#f92672">/</span><span style="color:#a6e22e">pre</span>&gt;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>[<span style="color:#ae81ff">1</span>]: <span style="color:#a6e22e">https</span>:<span style="color:#75715e">//sheepbao.github.io/post/golang_code_specification/?hmsr=toutiao.io&amp;utm_medium=toutiao.io&amp;utm_source=toutiao.io
</span></span></span></code></pre></div>
    </article>
  </div>

  
  
  

  
</body>

</html>